/*
 Trabajo Practico 2 Ejercicio 5
 Cliente
 Entrega número: 2

 - Integrantes:
        - Cortez, Martin        DNI: 30440023
        - Martinez, Guillermo   DNI: 34510461
        - Meli, Marcos          DNI: 31832759
        - Reyes, Leandro        DNI: 34213699
        - Rodriguez, Lucas      DNI: 34265017
*/

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <limits.h>
#include "fifo/fifo.h"

int status=-1,firstrun=1;
pid_t server_pid=0;

void usr1_handler(int);
void term_handler(int);
void alrm_handler(int);

static void usr2_handler(int sig, siginfo_t *siginfo, void *context)
{
	if(!server_pid)
		server_pid=siginfo->si_pid;
}

void main(int argc, char *argv[])
{
	int num=0,ret_val,pipe2,min=0,max=0,prom=0,cant=0;
	FILE* log;
	FILE* pipeline;
	struct sigaction act;
	char buffer[256];
	t_cola cola;
	t_info_fifo info_fifo;

	if(argc != 2)
		exit(printf("Argumentos inválidos\n"));

	printf("Cliente lanzado...\n");

	crearcola(&cola);

	signal(SIGUSR1,usr1_handler);
	signal(SIGTERM,term_handler);
	signal(SIGALRM,alrm_handler);

	memset (&act, '\0', sizeof(act));
	act.sa_sigaction = &usr2_handler;
	act.sa_flags = SA_SIGINFO;

	if (sigaction(SIGUSR2, &act, NULL) < 0)
	{
		perror ("Error en Sigaction");
		exit(1);
	}

	// Apertura de pipes como escritura
	ret_val = mkfifo(argv[1],0666);
	pipeline=fopen(argv[1],"w");
	fprintf(pipeline,"%d-",getpid());
	fclose(pipeline);

	/* 1 */

   // Apertura de pipes como lectura
   pause();
   pipe2=open(argv[1],O_RDONLY | O_NONBLOCK);

   while(1)
   {
   	pause();

   	if(status)
   	{
			read(pipe2,buffer,sizeof(buffer));
			sscanf(buffer,"%d-",&num);

   		// Acolo entrada
   		info_fifo.num=num;
         ponerencola(&cola, &info_fifo);

         // Calculos
         if(max<num)
         	max=num;

         if(min > num || firstrun == 1)
         {
         	min=num;
         	firstrun=0;
         }

         prom+=num;
         cant++;
   	}

   	else
   	{
			sprintf(buffer,"cliente_%d",getpid());
   		log=fopen(buffer,"wt");
   		
   		if(cant == 0)
   			fprintf(log,"No hubo números asignados por el servidor:\n");
   		
   		else
   		{
   		   fprintf(log,"Numeros asignados por el servidor:\n");

				while(!colavacia(&cola))
				{
					sacardecola(&cola, &info_fifo);
					fprintf(log,"%d\n",info_fifo.num);
				}
	
				fprintf(log,"Minimo: %d | Máximo: %d | Promedio: %d\n",min,max,cant!=0 ? prom/cant : 0);
			}
			
   		printf("Terminando\n");
   		fcloseall();
			kill(server_pid,SIGTERM);
   		exit(0);
		}

   	status=-1;
	}
}

void usr1_handler(int signal)
{
	status=1;
}

void term_handler(int signal)
{
	status=0;
	if(firstrun)
		alarm(1);
}

void alrm_handler(int signal)
{
}